Skip to content

fix(schema): keep 3.3 additions off the deprecated create_media_buy and update_media_buy (#8501) - #8767

Merged
bokelley merged 3 commits into
mainfrom
fix/8501-media-buy-deprecated-task-withdrawals
Nov 12, 2026
Merged

bokelley merged 3 commits into
mainfrom
fix/8501-media-buy-deprecated-task-withdrawals

Conversation

@bokelley

@bokelley bokelley commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

#8758 merged as 18da1a4559. This branch is rebased onto that main, so the diff shows only this PR's three commits: f37d95b0b0, 2f1a2f6021 and cc1534b698. The tree is identical to the previous green head 1ad545ea26, because #8758's squash merge has the same tree as its last head d2d905a547.

create_media_buy and update_media_buy are deprecated compatibility tasks, so 3.3 adds nothing to them. A field that exists only on a task buyers are moving off is one more gap for every migration. This PR removes the six fields the 3.3 betas added to those two tasks. The live tasks keep every one that they also carry.

This covers the create_media_buy / update_media_buy rows of the "Deprecated-task fields outside the 26" table in #8501, plus counting_mechanisms for get_products, because that field has one shared definition. It is a beta-to-beta change: no stable release carried these fields.

Field Removed from Where it lives in 3.3
predecessor_media_buy_id, lineage_reason (experimental media_buy.lineage) create_media_buy request buy_products and accept_proposal requests; get_media_buys readback and filter; core/media-buy.json
artifact_webhook.signing_profile (experimental) create_media_buy request, with its not: {required: [authentication, signing_profile]} Nowhere; no live task has artifact_webhook. Without authentication, deliveries are signed with adcp/webhook-signing/v1.
start_requires_all_creatives_approved package-request.json (create packages, update new_packages), package-update.json, core/package.json (create/update package readback) control_media_buy (package-control.json), get_media_buys package readback, update_creative_start_policy, media_buy.features.creative_start_policy
target_audiences[] (experimental media_buy.audience_evidence_targets) package-request.json Nowhere: with #8758 withdrawing the get_products copy, no 3.3 wire form remains (see the cleanup below). Purchases and list_products offer filters gain it in 4.0: purchase_target_audiences_required_in_4_0.
trackers, landing_page_url on assignments core/creative-assignment.json (used only by create/update requests and their package readback) sync_creatives assignment_operations assign; read back on list_creatives and get_media_buys
billing_measurement.counting_mechanisms[] (experimental) core/measurement-terms.json: covers create_media_buy, update_media_buy and get_products Nowhere in 3.3. The canonical commercial terms, held closed until 4.0, gain it then: canonical_counting_mechanisms_required_in_4_0, with the design recorded on the 4.0 page. vendor_metric_provenance[] and enums/collection-mechanism.json stay.

expected_confirmation_at stays everywhere.

get_media_buys doesn't read core/creative-assignment.json. It defines its own assignment rows, so no split was needed to keep readback.

What else changes

  • Training agent. create_media_buy and update_media_buy now ignore the withdrawn fields, as docs/reference/versioning.mdx requires for unknown fields: "Readers MUST ignore unknown fields rather than erroring". Assignment trackers and landing_page_url are stripped before storage, so they are neither applied nor read back. Create and update responses don't echo assign-set ones either. Rows set through sync_creatives assign keep their settings and tracker-slot check through later non-assignment updates, and get_media_buys and list_creatives still read them back. Create and update no longer echo the start gate. get_media_buys still echoes it, and control_media_buy still rejects true, because the reference seller doesn't implement the gate.
  • Docs. The create/update/get_media_buys task references (the renewal example now uses buy_products), the media-buy spec (lineage, creative start policy), the sync_creatives assignment reset recipe, capabilities, experimental status, billing authority, the measurement taxonomy, and the Web Bot Auth profile.
  • Registry. v4-compatibility.yaml and the 4.0 page reword purchase_target_audiences_required_in_4_0 and canonical_counting_mechanisms_required_in_4_0.
  • Audience evidence targets retired (second commit). With both copies withdrawn, media_buy.audience_evidence_targets has no 3.3 wire form. core/audience-evidence-target.json and enums/audience-evidence-relationship.json are deleted along with their index.json entries. The feature is removed from experimental status and the changeset. The target-matching rules move from get_products.mdx into the preserved 4.0 design under purchase_target_audiences_required_in_4_0; a short withdrawal notice stays at the old anchor. The check keeps its id, and its detection no longer keys off the retired feature id. tests/audience-evidence-targets.test.cjs is retired (preserved at d9b5417bc), and its still-relevant assertions move to tests/deprecated-task-withdrawals.test.cjs. The stable inline audience-evidence relationship enums, collection-mechanism.json and vendor_metric_provenance stay.
  • No scripts/lint-additive-minor-baseline.json rows. Every field here sat on an open schema.

Rebased after #8866

Rebased onto main 18da1a4559 (after #8866, #8762, #8957 and #8758). Before #8758 merged, it was stacked on #8758's d2d905a547, on main 7dd93fe024. The local results below were taken on the earlier stack (main 2dc672e316). On the refreshed stack, build:schemas, lint:additive-minor, test:mcp-schema-projection 41/41, capabilities-structural-bounds 25/25 and the withdrawal, installment and service-commitment suites (50/50) pass. Per the release coordinator:

Testing

On the first stacked tree (main 2dc672e316 + #8758 db09bd59e8 + this PR's three commits, before the two refreshes, which changed only #8758's docs line and the base), run sequentially:

  • npm run build:schemas: pass.
  • npm run test:schemas: 1184/1184, plus premium-display 10/10 and geo-region 6/6, including tests/deprecated-task-withdrawals.test.cjs and fix(schema): withdraw 3.3 additions from get_products and sync_creatives assignments (#8501) #8758's tests/get-products-deprecated-withdrawals.test.cjs.
  • npm run test:mcp-schema-projection 41/41, npm run test:examples, npm run test:contracts 502/502, npm run test:audience-evidence 20/20 (the retired target suite is no longer part of it), npm run test:v4-compatibility-registry 19/19: pass.
  • npm run lint:additive-minor (4 recorded, 0 new), test:additive-minor, scripts/lint-v4-compatibility-registry.cjs, scripts/audit-oneof.mjs --check, npm run build:compliance -- --check (1882 references current), and the changeset scope check: pass.
  • Server vitest, the files this PR touches: assignment-operations 21/21, training-agent-creative-start-policy 12/12, training-agent-collections 10/10, served-release-shape 11/11, product-discovery-schema-parity 4/4.
    • Two neighbouring files time out at load ~100–150: training-agent-served-release-fields (a 10s hook) and one tenant-smoke case (15s). Both fail identically on main's server code at the same load, so they are environmental.
  • Pre-push: version sync, changeset policy and docs validation (58/58) pass. The local storyboard matrix was skipped with ADCP_SKIP_STORYBOARD_MATRIX=1 for load, as the playbook allows. CI's training-agent-storyboards job is the gate.

Local hook

All three commits were made with HUSKY=0, with the release coordinator's approval. The hook's server-unit stage (precommit:server-unit) times out at this load (1500s budget), so it was skipped for load. CI is the gate.

I ran the other hook steps by hand on the final tree, and they pass: npm run test:unit 1284/1284, the dynamic-import, format-identity and callApi guards, npm run typecheck, and the image check.

Merge timing

This merges only after the #8501 consent window closes on Fri 2026-11-13, before the 3.3 RC, and after #8758. static/schemas/source/** is Ladon-gated, so a human merges it.

Refs #8501

🤖 Generated with Claude Code

@bokelley
bokelley force-pushed the fix/8501-media-buy-deprecated-task-withdrawals branch from 1d9c5f4 to 20ef970 Compare November 6, 2026 12:18
@bokelley
bokelley changed the base branch from main to fix/8501-get-products-sync-creatives-withdrawals November 6, 2026 12:18
bokelley added a commit that referenced this pull request Nov 7, 2026
…erimental, and inventory the rest

Adds scripts/audit-schema-bounds.cjs and its inventory: every unbounded array and string in the schema source, by stability, request or response side and proposed limit, plus every property or collection list carried inline. Bounds the arrays and strings that are new in 3.3 or experimental: 646 maxItems/maxLength keywords in 152 schemas, written by `node scripts/audit-schema-bounds.cjs --apply`, which is idempotent and is the one command for regenerating the slice after a conflict. Stable fields are proposed for 4.0 in specs/collection-bounds-proposal.md and registered as schema_bounds_required_in_4_0.

Not bounded: get_adcp_capabilities and its referenced types (#8198), inline property and collection lists, five nodes the SDK generators cannot carry a bound on, and seven 3.3 beta fields that the #8501 withdrawal PRs (#8765, #8762, #8758, #8767) remove.

The script now compares with the highest 3.2.x release (3.2.8), the base lint-additive-minor uses. Build Check runs its --check-unreleased guard as npm run lint:schema-bounds, so every new 3.3 or experimental array or string arrives with a bound. The MCP parity compile limit moves from 1,376,000 to 1,378,000 bytes (the controller closure measures 1,377,055).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 7, 2026
…erimental, and inventory the rest

Adds scripts/audit-schema-bounds.cjs and its inventory: every unbounded array and string in the schema source, by stability, request or response side and proposed limit, plus every property or collection list carried inline. Bounds the arrays and strings that are new in 3.3 or experimental: 646 maxItems/maxLength keywords in 152 schemas, written by `node scripts/audit-schema-bounds.cjs --apply`, which is idempotent and is the one command for regenerating the slice after a conflict. Stable fields are proposed for 4.0 in specs/collection-bounds-proposal.md and registered as schema_bounds_required_in_4_0.

Not bounded: get_adcp_capabilities and its referenced types (#8198), inline property and collection lists, five nodes the SDK generators cannot carry a bound on, and seven 3.3 beta fields that the #8501 withdrawal PRs (#8765, #8762, #8758, #8767) remove.

The script now compares with the highest 3.2.x release (3.2.8), the base lint-additive-minor uses. Build Check runs its --check-unreleased guard as npm run lint:schema-bounds, so every new 3.3 or experimental array or string arrives with a bound. The MCP parity compile limit moves from 1,376,000 to 1,378,000 bytes (the controller closure measures 1,377,055).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 8, 2026
…erimental, and inventory the rest

Adds scripts/audit-schema-bounds.cjs and its inventory: every unbounded array and string in the schema source, by stability, request or response side and proposed limit, plus every property or collection list carried inline. Bounds the arrays and strings that are new in 3.3 or experimental: 648 maxItems/maxLength keywords in 152 schemas, written by `node scripts/audit-schema-bounds.cjs --apply`, which is idempotent and is the one command for regenerating the slice after a conflict. Stable fields are proposed for 4.0 in specs/collection-bounds-proposal.md and registered as schema_bounds_required_in_4_0.

Not bounded: get_adcp_capabilities and its referenced types (#8198), inline property and collection lists, five nodes the SDK generators cannot carry a bound on, and seven 3.3 beta fields that the #8501 withdrawal PRs (#8765, #8762, #8758, #8767) remove.

The script now compares with the highest 3.2.x release (3.2.8), the base lint-additive-minor uses. Build Check runs its --check-unreleased guard as npm run lint:schema-bounds, so every new 3.3 or experimental array or string arrives with a bound. The match_keys arrays #8446 added on product identity and TMP provider registration get maxItems 64, the cap media_buy.supported_match_keys already carries. The MCP parity compile limit moves from 1,384,000 to 1,386,000 bytes (the controller closure measures 1,385,040).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 8, 2026
…erimental, and inventory the rest

Adds scripts/audit-schema-bounds.cjs and its inventory: every unbounded array and string in the schema source, by stability, request or response side and proposed limit, plus every property or collection list carried inline. Bounds the arrays and strings that are new in 3.3 or experimental: 648 maxItems/maxLength keywords in 152 schemas, written by `node scripts/audit-schema-bounds.cjs --apply`, which is idempotent and is the one command for regenerating the slice after a conflict. Stable fields are proposed for 4.0 in specs/collection-bounds-proposal.md and registered as schema_bounds_required_in_4_0.

Not bounded: get_adcp_capabilities and its referenced types (#8198), inline property and collection lists, five nodes the SDK generators cannot carry a bound on, and seven 3.3 beta fields that the #8501 withdrawal PRs (#8765, #8762, #8758, #8767) remove.

The script now compares with the highest 3.2.x release (3.2.8), the base lint-additive-minor uses. Build Check runs its --check-unreleased guard as npm run lint:schema-bounds, so every new 3.3 or experimental array or string arrives with a bound. The match_keys arrays #8446 added on product identity and TMP provider registration get maxItems 64, the cap media_buy.supported_match_keys already carries. The MCP parity compile limit moves from 1,384,000 to 1,386,000 bytes (the controller closure measures 1,385,040).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 8, 2026
…erimental, and inventory the rest

Adds scripts/audit-schema-bounds.cjs and its inventory: every unbounded array and string in the schema source, by stability, request or response side and proposed limit, plus every property or collection list carried inline. Bounds the arrays and strings that are new in 3.3 or experimental: 648 maxItems/maxLength keywords in 152 schemas, written by `node scripts/audit-schema-bounds.cjs --apply`, which is idempotent and is the one command for regenerating the slice after a conflict. Stable fields are proposed for 4.0 in specs/collection-bounds-proposal.md and registered as schema_bounds_required_in_4_0.

Not bounded: get_adcp_capabilities and its referenced types (#8198), inline property and collection lists, five nodes the SDK generators cannot carry a bound on, and seven 3.3 beta fields that the #8501 withdrawal PRs (#8765, #8762, #8758, #8767) remove.

The script now compares with the highest 3.2.x release (3.2.8), the base lint-additive-minor uses. Build Check runs its --check-unreleased guard as npm run lint:schema-bounds, so every new 3.3 or experimental array or string arrives with a bound. The match_keys arrays #8446 added on product identity and TMP provider registration get maxItems 64, the cap media_buy.supported_match_keys already carries. The MCP parity compile limit moves from 1,384,000 to 1,386,000 bytes (the controller closure measures 1,385,040).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit to adcontextprotocol/adcp-client-python that referenced this pull request Nov 8, 2026
…media_buy (#1872)

A control_media_buy package that sets start_requires_all_creatives_approved:
true now reaches the handler only when the seller declares
media_buy.features.creative_start_policy: true. Otherwise the dispatcher
answers UNSUPPORTED_FEATURE before the handler runs (recovery correctable,
field packages[N].start_requires_all_creatives_approved for the first opted-in
package, details.fields listing every one, mutation_outcome not_applied), as
AdCP 3.3 requires. false and omission are always allowed and read no
capabilities.

The declaration is the seller's own: PlatformHandler reads its request-scoped
DecisioningCapabilities (get_adcp_capabilities_for_request included), and any
other ADCPHandler reads its own get_adcp_capabilities response, through the new
ADCPHandler._declared_capabilities_for_request hook. The check applies to
handlers on AdCP 3.3 or later, like changed_paths enforcement.

create_media_buy and update_media_buy are not checked: AdCP 3.3 withdraws the
field from their packages (adcontextprotocol/adcp#8767) and their open schemas
ignore it (DR-0009).

BREAKING CHANGE: control_media_buy refuses
packages[].start_requires_all_creatives_approved: true with UNSUPPORTED_FEATURE
before the handler runs when the seller's capabilities do not declare
media_buy.features.creative_start_policy: true. A seller that honors the gate
declares the feature.

Closes #1869

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bokelley
bokelley force-pushed the fix/8501-get-products-sync-creatives-withdrawals branch from 58e0269 to db09bd5 Compare November 12, 2026 16:42
@bokelley
bokelley force-pushed the fix/8501-media-buy-deprecated-task-withdrawals branch from 20ef970 to a63c209 Compare November 12, 2026 16:54
@bokelley
bokelley changed the base branch from fix/8501-get-products-sync-creatives-withdrawals to main November 12, 2026 16:59
@bokelley
bokelley force-pushed the fix/8501-media-buy-deprecated-task-withdrawals branch from a63c209 to fe9a125 Compare November 12, 2026 17:05
@bokelley
bokelley marked this pull request as ready for review November 12, 2026 17:21

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Escalate to human review

Escalate — gated protocol-schema paths require human/CODEOWNERS approval.

This PR withdraws the 3.3 beta additions across the published protocol surface (static/schemas/source/**), including schema deletions (audience-evidence-target.json, audience-evidence-relationship.json, price-adjustments.json, price-adjustments-mismatch.json, package-forecast-input.json) and numerous modifications, plus matching docs and two minor changesets. The reviewer found no blocking, High, or Medium issues and confirmed changeset class, schema↔docs coherence, oneOf baseline pruning, and the absence of dangling $refs.

Despite the clean review, this PR touches gated_paths: true files and review_decision is REVIEW_REQUIRED (not APPROVED). Per the hard gated-paths gate (decision row 2), the outcome must be escalate until a human/CODEOWNERS approval lands.

Escalation reasons

  • Gated protocol-schema files under static/schemas/source/** were modified/deleted; review_decision is REVIEW_REQUIRED, so human/CODEOWNERS approval is required before merge.
  • Schema deletions in a sensitive path (static/schemas/source/**) warrant explicit human review of the wire-surface withdrawal.

No blocking findings; this escalation is about the approval gate, not code defects.

Why human review

  • Gated paths: files under static/schemas/source/** were modified/deleted and review_decision is REVIEW_REQUIRED (not APPROVED) — human/CODEOWNERS approval required (decision row 2).
  • Schema deletions in the published protocol surface (audience-evidence-target.json, audience-evidence-relationship.json, price-adjustments.json, price-adjustments-mismatch.json, package-forecast-input.json) merit explicit human review.
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/core/audience-evidence-target.json (deleted) matches static/schemas/source/**; static/schemas/source/core/creative-assignment.json (modified) matches static/schemas/source/**; static/schemas/source/core/execution-requirement-readiness.json (modified) matches static/schemas/source/**; static/schemas/source/core/measurement-terms.json (modified) matches static/schemas/source/**; static/schemas/source/core/media-buy-features.json (modified) matches static/schemas/source/**; static/schemas/source/core/package.json (modified) matches static/schemas/source/**; static/schemas/source/core/product-execution-readiness.json (modified) matches static/schemas/source/**; static/schemas/source/core/product-execution-requirement.json (modified) matches static/schemas/source/**; static/schemas/source/core/product-filters.json (modified) matches static/schemas/source/**; static/schemas/source/core/product.json (modified) matches static/schemas/source/**; static/schemas/source/core/targeting-overlay-support.json (modified) matches static/schemas/source/**; static/schemas/source/creative/sync-creatives-request.json (modified) matches static/schemas/source/**; static/schemas/source/enums/audience-evidence-relationship.json (deleted) matches static/schemas/source/**; static/schemas/source/enums/collection-mechanism.json (modified) matches static/schemas/source/**; static/schemas/source/error-details/price-adjustments-mismatch.json (deleted) matches static/schemas/source/**; static/schemas/source/index.json (modified) matches static/schemas/source/**; static/schemas/source/media-buy/create-media-buy-request.json (modified) matches static/schemas/source/**; static/schemas/source/media-buy/get-products-rejected.json (modified) matches static/schemas/source/**; static/schemas/source/media-buy/get-products-request.json (modified) matches static/schemas/source/**; static/schemas/source/media-buy/get-products-response.json (modified) matches static/schemas/source/**; static/schemas/source/media-buy/list-products-request.json (modified) matches `static/schemas/sour

…(truncated)…

@aao-secretariat aao-secretariat Bot added the ladon/needs-human-review Ladon has escalated this PR for human review. label Nov 12, 2026
@bokelley
bokelley force-pushed the fix/8501-media-buy-deprecated-task-withdrawals branch from fe9a125 to e819789 Compare November 12, 2026 18:50

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Escalate to human review

Escalate — gated schema paths require human/CODEOWNERS approval and the change includes breaking-class schema deletions.

No blocking (critical/high) findings: the reviewer confirms a clean pass. The withdrawal of six 3.3-beta fields from deprecated create_media_buy/update_media_buy tasks is coherent across schema, docs, server logic, and tests; no dangling $ref after the audience-evidence deletions; changeset classification is defensible; no undiscriminated oneOf; no dist/** mutation.

However this PR touches files under static/schemas/source/**, a hard, non-overridable approval gate (gated_paths: true), and the current review_decision is REVIEW_REQUIRED, not APPROVED. Per decision row 2, the outcome must be escalate until a human/CODEOWNERS approval is recorded.

Escalation reasons:

  • Gated paths: files under static/schemas/source/** were modified/deleted and review_decision is REVIEW_REQUIRED (not APPROVED). Human/CODEOWNERS approval is required before merge (decision row 2).
  • Schema deletions on the published protocol surface (audience-evidence-target.json, audience-evidence-relationship.json, price-adjustments.json, price-adjustments-mismatch.json, package-forecast-input.json) are breaking-class changes. Per the repo's "Breaking-class changes are never auto-approved" hard gate, ratification is a human act.

No fresh blocking findings exist, but the gated-path and breaking-class gates stand until a human approval is recorded.

Why human review

  • Gated paths: files under static/schemas/source/** were modified/deleted and review_decision is REVIEW_REQUIRED (not APPROVED) — human/CODEOWNERS approval required before merge (decision row 2).
  • Breaking-class schema deletions on the published protocol surface (audience-evidence-target.json, audience-evidence-relationship.json, price-adjustments.json, price-adjustments-mismatch.json, package-forecast-input.json) — breaking-class changes are never auto-approved; ratification is a human act.
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/core/audience-evidence-target.json (deleted) matches static/schemas/source/**; static/schemas/source/core/creative-assignment.json (modified) matches static/schemas/source/**; static/schemas/source/core/execution-requirement-readiness.json (modified) matches static/schemas/source/**; static/schemas/source/core/measurement-terms.json (modified) matches static/schemas/source/**; static/schemas/source/core/media-buy-features.json (modified) matches static/schemas/source/**; static/schemas/source/core/package.json (modified) matches static/schemas/source/**; static/schemas/source/core/product-execution-readiness.json (modified) matches static/schemas/source/**; static/schemas/source/core/product-execution-requirement.json (modified) matches static/schemas/source/**; static/schemas/source/core/product-filters.json (modified) matches static/schemas/source/**; static/schemas/source/core/product.json (modified) matches static/schemas/source/**; static/schemas/source/core/targeting-overlay-support.json (modified) matches static/schemas/source/**; static/schemas/source/creative/sync-creatives-request.json (modified) matches static/schemas/source/**; static/schemas/source/enums/audience-evidence-relationship.json (deleted) matches static/schemas/source/**; static/schemas/source/enums/collection-mechanism.json (modified) matches static/schemas/source/**; static/schemas/source/error-details/price-adjustments-mismatch.json (deleted) matches static/schemas/source/**; static/schemas/source/index.json (modified) matches static/schemas/source/**; static/schemas/source/media-buy/create-media-buy-request.json (modified) matches static/schemas/source/**; static/schemas/source/media-buy/get-products-rejected.json (modified) matches static/schemas/source/**; static/schemas/source/media-buy/get-products-

…(truncated)…

@bokelley
bokelley force-pushed the fix/8501-media-buy-deprecated-task-withdrawals branch from e819789 to 1ad545e Compare November 12, 2026 19:07

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Escalate to human review

Escalate — hard gated-paths gate unsatisfied + breaking-class schema withdrawals require human ratification.

This PR withdraws 3.3-beta additions from deprecated tasks (adcp#8501): it deletes several published-surface schemas and modifies many others across static/schemas/source/**. The reviewer reports a clean pass — schema removals have no dangling $refs, docs track every removal in lockstep, the get_products→list_products execution_readiness move is consistent across schema/docs/compliance, and the task-handlers.ts refactor is correct. No Critical/High/Medium findings.

Despite the clean diff, two hard gates prevent auto-approval:

  1. Gated paths (decision row 2): gated_paths: true — 35 files under static/schemas/source/** were modified/deleted — and review_decision is REVIEW_REQUIRED, not APPROVED. The gate only lifts on a real human/CODEOWNERS approval.

  2. Breaking-class governance (prose hard gate): this PR deletes published protocol schemas (audience-evidence-target.json, enums/audience-evidence-relationship.json, pricing-options/price-adjustments.json, error-details/price-adjustments-mismatch.json, media-buy/package-forecast-input.json). Schema deletions on the published surface are breaking-class; per the constitution these are never auto-approved — ratification is a human act. review_decision is not APPROVED, so the gate's escalation instruction stands.

Sticky with the prior escalate: both gates still hold on the current head. Human/CODEOWNERS approval is required before merge. No blocking code findings — the only barrier is the required human ratification of breaking-class schema changes under a hard approval gate.

Why human review

  • Gated paths: 35 files under static/schemas/source/** were modified/deleted and review_decision is REVIEW_REQUIRED (not APPROVED) — human/CODEOWNERS approval required before merge (decision row 2).
  • Breaking-class schema deletions on the published protocol surface (audience-evidence-target.json, enums/audience-evidence-relationship.json, pricing-options/price-adjustments.json, error-details/price-adjustments-mismatch.json, media-buy/package-forecast-input.json) — breaking-class changes are never auto-approved; ratification is a human act and review_decision is not APPROVED.
  • High-risk deletions in a sensitive path (static/schemas/source/**) are hard to recover from if wrong and merit explicit human review.
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/core/audience-evidence-target.json (deleted) matches static/schemas/source/**; static/schemas/source/core/creative-assignment.json (modified) matches static/schemas/source/**; static/schemas/source/core/execution-requirement-readiness.json (modified) matches static/schemas/source/**; static/schemas/source/core/measurement-terms.json (modified) matches static/schemas/source/**; static/schemas/source/core/media-buy-features.json (modified) matches static/schemas/source/**; static/schemas/source/core/package.json (modified) matches static/schemas/source/**; static/schemas/source/core/product-execution-readiness.json (modified) matches static/schemas/source/**; static/schemas/source/core/product-execution-requirement.json (modified) matches static/schemas/source/**; static/schemas/source/core/product-filters.json (modified) matches static/schemas/source/**; static/schemas/source/core/product.json (modified) matches static/schemas/source/**; static/schemas/source/core/targeting-overlay-support.json (modified) matches static/schemas/source/**; static/schemas/source/creative/sync-creatives-request.json (modified) matches static/schemas/source/**; static/schemas/source/enums/audience-evidence-relationship.json (deleted) matches static/schemas/source/**; static/schemas/source/enums/collection-mechanism.json (modified) matches static/schemas/source/**; static/schemas/source/error-details/p

…(truncated)…

…nd update_media_buy (#8501)

create_media_buy and update_media_buy are deprecated compatibility tasks, so
3.3 adds nothing to them. Six fields the 3.3 betas added to them are removed;
the live tasks keep every one they also carry.

- predecessor_media_buy_id, lineage_reason: off create_media_buy; stay on
  buy_products, accept_proposal and get_media_buys.
- artifact_webhook.signing_profile: off create_media_buy; no live task has
  artifact_webhook, so it is signed with adcp/webhook-signing/v1.
- start_requires_all_creatives_approved: off package-request, package-update
  and core/package.json; stays on control_media_buy and get_media_buys.
- target_audiences: off package-request; with #8758 withdrawing the
  get_products copy, no 3.3 wire form remains.
- trackers, landing_page_url: off core/creative-assignment.json; stay on
  sync_creatives assign, list_creatives and get_media_buys.
- billing_measurement.counting_mechanisms: off core/measurement-terms.json
  (create, update and get_products); the canonical terms gain it in 4.0.

The training agent ignores the withdrawn fields on create/update, as the
versioning rules require for unknown fields, and no longer echoes them in
create/update responses; get_media_buys still reads back what assign set.
The 4.0 registry and the task references say where each field lives; the
3.3 release pages are left to #8883. Text that called the purchase,
offer-filter or canonical measurement schemas closed now says what #8866
left: the first two are open but don't define the field, and the
canonical terms are held closed with the commercial terms until 4.0.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley and others added 2 commits November 12, 2026 19:59
…rm remains (#8501)

With filters.target_audiences withdrawn from get_products (#8758) and the
package copy withdrawn from create_media_buy and update_media_buy, the
experimental media_buy.audience_evidence_targets has no 3.3 wire form.

- Delete core/audience-evidence-target.json and
  enums/audience-evidence-relationship.json and their index.json entries.
  The stable inline relationship enums on audience evidence stay.
- Drop the feature from the changeset. Its experimental-status row went
  with the previous commit, and the 3.3 release pages are left to #8883.
- Move the target-matching rules from get_products.mdx into the preserved
  4.0 design under purchase_target_audiences_required_in_4_0, keeping a short
  withdrawal notice at the old anchor; the check keeps its id and its
  detection no longer keys off the retired feature id.
- Retire tests/audience-evidence-targets.test.cjs (preserved at d9b5417)
  and stop reading the deleted package-forecast-input.json in
  tests/creative-start-policy.test.cjs.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The release notes, What's new, the 3.2 to 3.3 migration guide and the 3.3
beta page belong to #8883. This PR no longer edits them, so its test stops
asserting their "Withdrawn from the deprecated tasks" heading.

Refs #8501

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bokelley
bokelley force-pushed the fix/8501-media-buy-deprecated-task-withdrawals branch from 1ad545e to cc1534b Compare November 12, 2026 20:00

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Escalate to human review

Escalate — hard gated-paths gate not satisfied, and breaking-class schema deletions on the published protocol surface require human ratification.

This PR withdraws six 3.3-beta fields from the deprecated create_media_buy/update_media_buy tasks (adcp#8501). The reviewer pass is clean: schema↔docs coherence verified across all removals, no dangling $ref to the two deleted schemas, sound server refactor in task-handlers.ts, and a correct minor changeset for open-schema beta fields that never reached GA. No Critical/High/Medium findings.

Despite the clean diff, two hard gates apply:

Gated paths (decision row 2): 12 files under static/schemas/source/** were modified/deleted and review_decision is REVIEW_REQUIRED (not APPROVED). This path is under a hard, non-overridable approval gate — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.

Breaking-class deletions: Two published schemas are deleted — static/schemas/source/core/audience-evidence-target.json and static/schemas/source/enums/audience-evidence-relationship.json. Per the repo's "Breaking-class changes are never auto-approved" hard gate, ratification is a human act and must be escalated unless review_decision is APPROVED.

Escalation reasons:

  • Gated paths: 12 files under static/schemas/source/** modified/deleted with review_decision = REVIEW_REQUIRED — human/CODEOWNERS approval required (row 2).
  • Deletes static/schemas/source/core/audience-evidence-target.json and static/schemas/source/enums/audience-evidence-relationship.json — breaking-class removals on the published protocol surface; never auto-approved.
  • High-risk deletions in a sensitive path (static/schemas/source/**) are hard to recover from and merit explicit human review (row 3).

Net improvement vs prior run noted: the earlier escalation referenced additional breaking deletions (pricing-options/price-adjustments.json, error-details/price-adjustments-mismatch.json, media-buy/package-forecast-input.json) no longer present in this delta. The remaining escalation is governance, not a reviewer defect.

Why human review

  • Gated paths: 12 files under static/schemas/source/** were modified/deleted and review_decision is REVIEW_REQUIRED (not APPROVED) — human/CODEOWNERS approval required before merge (decision row 2).
  • Deletes static/schemas/source/core/audience-evidence-target.json and static/schemas/source/enums/audience-evidence-relationship.json — breaking-class removals on the published protocol surface; breaking-class changes are never auto-approved and ratification is a human act (review_decision is not APPROVED).
  • High-risk deletions in a sensitive path (static/schemas/source/**) are hard to recover from if wrong and merit explicit human review (decision row 3).
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/core/audience-evidence-target.json (deleted) matches static/schemas/source/**; static/schemas/source/core/creative-assignment.json (modified) matches static/schemas/source/**; static/schemas/source/core/measurement-terms.json (modified) matches static/schemas/source/**; static/schemas/source/core/media-buy-features.json (modified) matches static/schemas/source/**; static/schemas/source/core/package.json (modified) matches static/schemas/source/**; static/schemas/source/enums/audience-evidence-relationship.json (deleted) matches static/schemas/source/**; static/schemas/source/enums/collection-mechanism.json (modified) matches static/schemas/source/**; static/schemas/source/index.json (modified) matches static/schemas/source/**; static/schemas/source/media-buy/create-media-buy-request.json (modified) matches static/schemas/source/**; static/schemas/source/media-buy/package-request.json (modified) matches static/schemas/source/**; static/schemas/source/media-buy/package-update.js

…(truncated)…

@bokelley
bokelley merged commit 3deb1cf into main Nov 12, 2026
68 checks passed
@bokelley
bokelley deleted the fix/8501-media-buy-deprecated-task-withdrawals branch November 12, 2026 20:40
bokelley added a commit that referenced this pull request Nov 12, 2026
… surfaces

#8758 and #8767 merged and handed their release-doc text to #8883. Drop
#8767 from the dependency markers, and bring the lines that still
described withdrawn surfaces as current in line with main:

- media_buy.price_adjustments and media_buy.audience_evidence_targets are
  withdrawn at rc.0 and no longer registered (experimental table, feature
  index, What's new, migration guide).
- execution_readiness is on list_products; lineage is on buy_products and
  accept_proposal; collection cards leave get_products; the creative start
  gate is set through control_media_buy; counting_mechanisms leaves
  measurement_terms; assignment trackers and landing pages stay only on
  sync_creatives assign operations.
- Point the price-adjustment and target-audience links at the withdrawn
  sections; refresh the #8501 row of the in-review table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Synaeve added a commit to Synaeve/adcp that referenced this pull request Nov 13, 2026
conflicts
- tests/mcp-schema-projection.test.cjs: keep main's 1_388_000 bound and
  its comment; record the merged controller at 1_330_443 bytes (main
  1_329_553 after adcontextprotocol#8758 and adcontextprotocol#8767, errata +890)

auto-merged
- sync_creatives, media-products, product.json and the training agent:
  the adcontextprotocol#8501 withdrawals touch assignment, pricing and audience text,
  not the errata wording, which is unchanged
bokelley added a commit that referenced this pull request Nov 13, 2026
… surfaces

#8758 and #8767 merged and handed their release-doc text to #8883. Drop
#8767 from the dependency markers, and bring the lines that still
described withdrawn surfaces as current in line with main:

- media_buy.price_adjustments and media_buy.audience_evidence_targets are
  withdrawn at rc.0 and no longer registered (experimental table, feature
  index, What's new, migration guide).
- execution_readiness is on list_products; lineage is on buy_products and
  accept_proposal; collection cards leave get_products; the creative start
  gate is set through control_media_buy; counting_mechanisms leaves
  measurement_terms; assignment trackers and landing pages stay only on
  sync_creatives assign operations.
- Point the price-adjustment and target-audience links at the withdrawn
  sections; refresh the #8501 row of the in-review table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
… surfaces

#8758 and #8767 merged and handed their release-doc text to #8883. Drop
#8767 from the dependency markers, and bring the lines that still
described withdrawn surfaces as current in line with main:

- media_buy.price_adjustments and media_buy.audience_evidence_targets are
  withdrawn at rc.0 and no longer registered (experimental table, feature
  index, What's new, migration guide).
- execution_readiness is on list_products; lineage is on buy_products and
  accept_proposal; collection cards leave get_products; the creative start
  gate is set through control_media_buy; counting_mechanisms leaves
  measurement_terms; assignment trackers and landing pages stay only on
  sync_creatives assign operations.
- Point the price-adjustment and target-audience links at the withdrawn
  sections; refresh the #8501 row of the in-review table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
… surfaces

#8758 and #8767 merged and handed their release-doc text to #8883. Drop
#8767 from the dependency markers, and bring the lines that still
described withdrawn surfaces as current in line with main:

- media_buy.price_adjustments and media_buy.audience_evidence_targets are
  withdrawn at rc.0 and no longer registered (experimental table, feature
  index, What's new, migration guide).
- execution_readiness is on list_products; lineage is on buy_products and
  accept_proposal; collection cards leave get_products; the creative start
  gate is set through control_media_buy; counting_mechanisms leaves
  measurement_terms; assignment trackers and landing pages stay only on
  sync_creatives assign operations.
- Point the price-adjustment and target-audience links at the withdrawn
  sections; refresh the #8501 row of the in-review table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
…#8968)

Add experimental installment_refs (media_buy.installment_creative_assignment)
to the sync_creatives assign and replace operations: an array of
core/canonical-installment-ref.json, unique, 1 to 500 (a canonical product's
installments cap). Present, the assignment applies only to those installments
of the package; absent, to every installment, as before.

- Within one installment, weight, rotation and placement routing work
  unchanged; placement routing and installment scope intersect, and an
  installment no assignment applies to gets no other installment's creative.
- Each ref names an installment in the purchased product's installments, else
  VALIDATION_ERROR. A change to an installment past its change_cutoff is
  refused with CREATIVE_DEADLINE_EXCEEDED, never accepted silently. No new
  error codes.
- A supplied list replaces the scope; omission on an assign upsert keeps it.
  replace transfers the scope unless it supplies one, merge moves it, and
  unassign and merge reject installment_refs by name.
- Readback on get_media_buys packages[].creative_approvals[] and
  list_creatives assignments.assigned_packages[], omitted for an assignment
  on every installment.
- Buyers send it only to sellers listing the feature (versioning rule 4);
  others reject it with UNSUPPORTED_FEATURE. New experimental-status row.

Not on core/creative-assignment.json, the deprecated create_media_buy and
update_media_buy rows, or the deprecated sync_creatives assignments[] row:
3.3 adds nothing to deprecated tasks (#8501, #8767).

Docs: sync_creatives section with a two-post creator example, a creator-brief
section in collections-and-installments, readback rows. Tests:
tests/installment-creative-assignment.test.cjs in test:schemas.

Committed with HUSKY=0: precommit:server-unit hit its 1500s budget at host
load ~110-140. Its timed-out files pass alone; the other hook steps were run
by hand and pass. No server file is touched.

Refs #8968

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
… (experimental) (#8972)

* feat(schema): assign a creative to specific installments of a package (#8968)

Add experimental installment_refs (media_buy.installment_creative_assignment)
to the sync_creatives assign and replace operations: an array of
core/canonical-installment-ref.json, unique, 1 to 500 (a canonical product's
installments cap). Present, the assignment applies only to those installments
of the package; absent, to every installment, as before.

- Within one installment, weight, rotation and placement routing work
  unchanged; placement routing and installment scope intersect, and an
  installment no assignment applies to gets no other installment's creative.
- Each ref names an installment in the purchased product's installments, else
  VALIDATION_ERROR. A change to an installment past its change_cutoff is
  refused with CREATIVE_DEADLINE_EXCEEDED, never accepted silently. No new
  error codes.
- A supplied list replaces the scope; omission on an assign upsert keeps it.
  replace transfers the scope unless it supplies one, merge moves it, and
  unassign and merge reject installment_refs by name.
- Readback on get_media_buys packages[].creative_approvals[] and
  list_creatives assignments.assigned_packages[], omitted for an assignment
  on every installment.
- Buyers send it only to sellers listing the feature (versioning rule 4);
  others reject it with UNSUPPORTED_FEATURE. New experimental-status row.

Not on core/creative-assignment.json, the deprecated create_media_buy and
update_media_buy rows, or the deprecated sync_creatives assignments[] row:
3.3 adds nothing to deprecated tasks (#8501, #8767).

Docs: sync_creatives section with a two-post creator example, a creator-brief
section in collections-and-installments, readback rows. Tests:
tests/installment-creative-assignment.test.cjs in test:schemas.

Committed with HUSKY=0: precommit:server-unit hit its 1500s budget at host
load ~110-140. Its timed-out files pass alone; the other hook steps were run
by hand and pass. No server file is touched.

Refs #8968

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(sync_creatives): validate the installment example in its test, not via $schema (#8968)

check-schema-links rejects /schemas/latest/ for a schema already released
in v3, and sync-creatives-request.json is released in 3.2.10, which lacks
installment_refs. Follow the assignment-trackers example: drop $schema from
the creator example and have tests/installment-creative-assignment.test.cjs
extract the block from the doc and validate it against the source schema.

Committed with HUSKY=0 for the same reason as the previous commit; this
commit touches one doc example and one root test file, both run locally.

Refs #8968

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(collections): tie installment_refs to chosen installments (#8968)

With #8967 (#8974) on main, the installments a package bought are the
selected set when the buyer chose installments through refine_proposals.
Link the new section from the creatives-per-installment paragraph.

Committed with HUSKY=0: a one-sentence docs change; staging docs/ runs the
full server unit suite, which exceeds its budget at current host load.

Refs #8968

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
… surfaces

#8758 and #8767 merged and handed their release-doc text to #8883. Drop
#8767 from the dependency markers, and bring the lines that still
described withdrawn surfaces as current in line with main:

- media_buy.price_adjustments and media_buy.audience_evidence_targets are
  withdrawn at rc.0 and no longer registered (experimental table, feature
  index, What's new, migration guide).
- execution_readiness is on list_products; lineage is on buy_products and
  accept_proposal; collection cards leave get_products; the creative start
  gate is set through control_media_buy; counting_mechanisms leaves
  measurement_terms; assignment trackers and landing pages stay only on
  sync_creatives assign operations.
- Point the price-adjustment and target-audience links at the withdrawn
  sections; refresh the #8501 row of the in-review table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
… surfaces

#8758 and #8767 merged and handed their release-doc text to #8883. Drop
#8767 from the dependency markers, and bring the lines that still
described withdrawn surfaces as current in line with main:

- media_buy.price_adjustments and media_buy.audience_evidence_targets are
  withdrawn at rc.0 and no longer registered (experimental table, feature
  index, What's new, migration guide).
- execution_readiness is on list_products; lineage is on buy_products and
  accept_proposal; collection cards leave get_products; the creative start
  gate is set through control_media_buy; counting_mechanisms leaves
  measurement_terms; assignment trackers and landing pages stay only on
  sync_creatives assign operations.
- Point the price-adjustment and target-audience links at the withdrawn
  sections; refresh the #8501 row of the in-review table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
… surfaces

#8758 and #8767 merged and handed their release-doc text to #8883. Drop
#8767 from the dependency markers, and bring the lines that still
described withdrawn surfaces as current in line with main:

- media_buy.price_adjustments and media_buy.audience_evidence_targets are
  withdrawn at rc.0 and no longer registered (experimental table, feature
  index, What's new, migration guide).
- execution_readiness is on list_products; lineage is on buy_products and
  accept_proposal; collection cards leave get_products; the creative start
  gate is set through control_media_buy; counting_mechanisms leaves
  measurement_terms; assignment trackers and landing pages stay only on
  sync_creatives assign operations.
- Point the price-adjustment and target-audience links at the withdrawn
  sections; refresh the #8501 row of the in-review table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
… surfaces

#8758 and #8767 merged and handed their release-doc text to #8883. Drop
#8767 from the dependency markers, and bring the lines that still
described withdrawn surfaces as current in line with main:

- media_buy.price_adjustments and media_buy.audience_evidence_targets are
  withdrawn at rc.0 and no longer registered (experimental table, feature
  index, What's new, migration guide).
- execution_readiness is on list_products; lineage is on buy_products and
  accept_proposal; collection cards leave get_products; the creative start
  gate is set through control_media_buy; counting_mechanisms leaves
  measurement_terms; assignment trackers and landing pages stay only on
  sync_creatives assign operations.
- Point the price-adjustment and target-audience links at the withdrawn
  sections; refresh the #8501 row of the in-review table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ladon/needs-human-review Ladon has escalated this PR for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant